home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 12
/
CU Amiga Magazine's Super CD-ROM 12 (1997)(EMAP Images)(GB)[!][issue 1997-07].iso
/
CUCD
/
Graphics
/
Gallery
/
Gallery.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-16
|
18KB
|
598 lines
#define __VERSION__ "39"
#define __REVISION__ "3"
#define __NAME__ "Gallery"
#define __AUTHOR__ "Markus Hillenbrand"
char *V = "$VER: " __NAME__ " " __VERSION__ "." __REVISION__ " (" __DATE__ ")";
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <GUIC_Classes/GUIC_System.hpp>
#include <GUIC_Classes/GUIC_Date.hpp>
#include <GUIC_Classes/GUIC_Error.hpp>
#include <GUIC_Classes/GUIC_Frame.hpp>
#include <GUIC_Classes/GUIC_Application.hpp>
#include <GUIC_Classes/GUIC_Screen.hpp>
#include <GUIC_Classes/GUIC_Window.hpp>
#include <GUIC_Classes/GUIC_Error.hpp>
#include <GUIC_Classes/GUIC_Exceptions.hpp>
#include <GUIC_Classes/GUIC_DirectoryExamine.hpp>
#include <GUIC_Classes/GUIC_FileExamine.hpp>
#include <GUIC_Classes/GUIC_File.hpp>
#include <GUIC_Classes/GUIC_Key.hpp>
#include <GUIC_Classes/GUIC_List.hpp>
#include <GUIC_Classes/GUIC_Node.hpp>
#include <GUIC_Classes/GUIC_Exceptions.hpp>
#include <GUIC_Classes/GUIC_Button.hpp>
#include <GUIC_Classes/GUIC_Checkbox.hpp>
#include <GUIC_Classes/GUIC_String.hpp>
#include <GUIC_Classes/GUIC_Integer.hpp>
#include <GUIC_Classes/GUIC_Slider.hpp>
#include <GUIC_Classes/GUIC_Label.hpp>
#include <GUIC_Classes/GUIC_SlidingInteger.hpp>
#include <GUIC_Classes/GUIC_FileString.hpp>
#include <GUIC_Classes/GUIC_PathString.hpp>
#include <GUIC_Classes/GUIC_Message.hpp>
#include <GUIC_Classes/GUIC_FileRequester.hpp>
#include <GUIC_Classes/GUIC_ProgramArgs.hpp>
#define COPYRIGHT "<SMALL> index file created with 'Gallery', (c) 1997 by <A HREF=\"http://www.student.uni-kl.de/~hillenbr\">Markus Hillenbrand</A> </SMALL>"
#define FILEFILTER "#?.(jpeg|jpg|gif|iff|ilbm|iff24|png|bmp|pcx|tiff)"
#define MINLINES 3
#define MINCOLUMNS 3
#define MAXLINES 200
#define MAXCOLUMNS 200
#define DEFAULTLINES 3
#define DEFAULTCOLUMNS 5
GUIC_ListC errorList;
int lastDay=0,lastMonth=0,lastYear=0;
class GalleryEntryC : public GUIC_ObjectC
{
public:
GalleryEntryC (STRPTR f, LONG s, int d, int m, int y) { fileName=f; size=s; day=d; month=m; year=y; }
int compare (GUIC_ObjectC &o);
void print (void) { cout << fileName << endl; }
String fileName;
int day,month,year;
LONG size;
protected:
void cleanUp(void) {};
};
int GalleryEntryC::compare(GUIC_ObjectC &o)
{
// First we must convert the argument to what it really is:
GalleryEntryC *g = (GalleryEntryC *)&o;
return strcmp(this->fileName, g->fileName); // Just compare the two file names
}
String makeThumbnail (GUIC_FileExamineC &file)
{
String fileName = file.getName();
int i = fileName.length();
while (--i) if (fileName[i] == '.') break;
String thumbName = fileName.left(i);
thumbName+="_.jpg";
try
{
GUIC_FileExamineC f(thumbName);
if (f.newer(file)) return thumbName;
}
catch (GUIC_SystemX &e) { }
String args = "<>NIL: \"" + fileName + "\" TO \"" + thumbName + "\" FORMAT JPEG QUALITY 90 BOXFIT 100 100";
cout << " - creating thumbnail for file '" << fileName << "' ... " << flush;
BOOL result = GUIC_SystemC::runProgram("GfxCon_68020", 100000, args);
if (result) cout << "done." << endl; else cout << "error occured." << endl;
return thumbName;
}
void createGallery (GUIC_ListC &fileList, STRPTR pattern, LONG linesInTable, LONG columnsInTable, BOOL picClick)
{
GalleryEntryC *key = (GalleryEntryC *)fileList.objectAt(1);
GUIC_FileExamineC firstFile(key->fileName);
String currentDir = firstFile.getPathPart();
ldiv_t d = ldiv ( fileList.length(), columnsInTable );
int lines = d.quot;
if (d.rem) lines++;
d = ldiv (lines, linesInTable);
int galleries = d.quot;
if (d.rem) galleries++;
cout << "Creating " << galleries << " galleries in directory '" << currentDir << "' " << endl;
fileList.sort();
GUIC_FileExamineC directoryName(currentDir);
// Create the index file with the frames
GUIC_FileC gallery(currentDir, "index.html", GUIC_Write);
gallery.write("<TITLE>Gallery '");
gallery.write(directoryName.getFilePart());
gallery.writeLn("'</TITLE>");
gallery.writeLn("<FRAMESET COLS=150,*>");
gallery.writeLn("<FRAME NAME=F1 SRC=\"galleries.html\" MarginHeight=0 MarginWidth=0 Scrolling=\"auto\" FrameBorder=0>");
gallery.writeLn("<FRAME NAME=F2 SRC=\"index1.html\" MarginHeight=0 MarginWidth=0 Scrolling=\"auto\" FrameBorder=0>");
gallery.writeLn("</FRAMESET>");
// now create the overview over the galleries
GUIC_FileC overview (currentDir, "galleries.html", GUIC_Write);
overview.writeLn("<HTML>");
overview.write("<H2>");
overview.write(directoryName.getFilePart());
overview.writeLn("</H2><BR>");
for (int i=1; i<=galleries; i++)
{
overview.write("<A HREF=\"index");
overview.write(i);
overview.write(".html\" TARGET=F2>Gallery ");
overview.write(i);
overview.writeLn("</A> <BR>");
}
overview.writeLn("<BR> <BR> <IMG SRC=internal-gopher-menu> <A HREF=\"../index.html\" TARGET=_top> up </A>");
overview.writeLn("</HTML>");
// create each gallery
int count = 0;
for (i=1; i<=galleries; i++)
{
char filename[256];
sprintf(filename, "index%ld.html", i);
GUIC_FileC indexFile(currentDir, filename, GUIC_Write);
// write head and title
indexFile.writeLn("<HTML>");
indexFile.writeLn("<HEAD>");
indexFile.write("<TITLE> "); indexFile.write(directoryName.getFilePart()); indexFile.writeLn(" </TITLE>");
indexFile.writeLn("</HEAD>");
indexFile.write("<BODY");
if (pattern)
{
indexFile.write(" Background=\"");
indexFile.write(pattern);
indexFile.write("\"");
}
indexFile.writeLn(">");
indexFile.write("<CENTER><H2>");
indexFile.write(directoryName.getFilePart());
indexFile.write("</H2> (Part ");
indexFile.write(i);
indexFile.write(" of ");
indexFile.write(galleries);
indexFile.writeLn(")<BR>");
indexFile.writeLn("<HR>");
indexFile.writeLn("<TABLE Border=1 CellSpacing=4 CellPadding=4>");
int boundary = count + columnsInTable*linesInTable;
if (boundary>fileList.length()) boundary = fileList.length();
for (int j=count; j<boundary; j++)
{
key = (GalleryEntryC *)fileList.objectAt(j+1);
GUIC_FileExamineC file(key->fileName);
String thumbName = "";
// Create the thumbnail now
try
{
thumbName = makeThumbnail(file);
GUIC_FileExamineC thumb (thumbName);
thumbName = thumb.getFilePart();
}
catch (GUIC_SystemX &e) { GalleryEntryC *s = new GalleryEntryC(key->fileName,0,0,0,0); errorList.addTail(*s); }
// Check the date
GUIC_DateC oldDate(lastDay,lastMonth,lastYear),*fileDate = file.getDate();;
if (fileDate->greater(oldDate) )
{
lastDay = fileDate->getDay();
lastMonth = fileDate->getMonth();
lastYear = fileDate->getYear();
}
// Check if there are 5 entries per line in the table
if (count++ % columnsInTable == 0) indexFile.write("<TR> ");
// write the picture data
indexFile.write("<TD> <CENTER>");
if (picClick)
{
indexFile.write("<A HREF=\"");
indexFile.write(file.getFilePart());
indexFile.write("\"> <IMG SRC=\"");
indexFile.write(thumbName);
indexFile.write("\" ALT=Thumbnail> <BR>");
}
else
{
indexFile.write("<IMG SRC=\"");
indexFile.write(thumbName);
indexFile.write("\" ALT=Thumbnail> <BR>");
indexFile.write("<A HREF=\"");
indexFile.write(file.getFilePart());
indexFile.write("\">");
}
indexFile.write(file.getFilePart());
indexFile.write(" </A> <BR> Size: ");
indexFile.write(key->size);
indexFile.write(" <BR> Date: ");
indexFile.write(key->day);
indexFile.write(".");
indexFile.write(key->month);
indexFile.write(".");
indexFile.write(key->year);
indexFile.writeLn("</TD>");
}
indexFile.writeLn("</TABLE>");
indexFile.writeLn("<HR>");
indexFile.writeLn(COPYRIGHT);
indexFile.writeLn("</BODY>");
indexFile.writeLn("</HTML>");
}
}
void createHTML (GUIC_ListC &fileList, STRPTR pattern)
{
GalleryEntryC *key = (GalleryEntryC *)fileList.objectAt(1);
GUIC_FileExamineC firstFile(key->fileName);
STRPTR currentDir = firstFile.getPathPart();
GUIC_FileC indexFile(currentDir, "index.html", GUIC_Write);
GUIC_FileExamineC directoryName(currentDir);
String titleString = directoryName.getFilePart();
if (titleString == String("") ) titleString = directoryName.getName();
cout << "Creating file '" << indexFile.getName() << "'" << endl;
indexFile.writeLn("<HTML>");
indexFile.writeLn("<HEAD>");
indexFile.write("<TITLE> "); indexFile.write(titleString); indexFile.writeLn(" </TITLE>");
indexFile.writeLn("</HEAD>");
indexFile.write("<BODY");
if (pattern)
{
indexFile.write(" Background=\"");
indexFile.write(pattern);
indexFile.write("\"");
}
indexFile.writeLn(">");
indexFile.write("<CENTER><H1>"); indexFile.write(titleString); indexFile.writeLn("</H1>");
indexFile.writeLn("<HR><BR><BR>");
// Create the table of galleries
indexFile.writeLn("<TABLE Border=1 CellSpacing=4 CellPadding=4>");
indexFile.writeLn("<TR> <TH> <CENTER> <H3> Gallery Name </H3> </TH> <TH> <CENTER> <H3> Entries </H3> </TH> <TH> <CENTER> <H3> Last Update </H3> </TH>");
fileList.sort();
for (int i=1; i<=fileList.length(); i++)
{
key = (GalleryEntryC *)fileList.objectAt(i);
GUIC_FileExamineC file (key->fileName);
indexFile.write("<TR> <TD> <CENTER> <A HREF=\"");
indexFile.write(file.getFilePart());
indexFile.write("/index.html\"");
indexFile.write("> ");
indexFile.write(file.getFilePart());
indexFile.write(" </A> </TD> <TD> <CENTER> ");
indexFile.write(key->size);
indexFile.write(" </TD> <TD> <CENTER> ");
if (key->day)
{
indexFile.write(key->day);
indexFile.write(".");
indexFile.write(key->month);
indexFile.write(".");
indexFile.write(key->year);
}
else indexFile.write("(Directory)");
indexFile.writeLn(" </TD>");
}
indexFile.writeLn("</TABLE>");
indexFile.writeLn("<BR> <IMG SRC=internal-gopher-menu> <A HREF=\"../index.html\" TARGET=_top> up </A> <BR>");
indexFile.writeLn("<HR>");
indexFile.writeLn(COPYRIGHT);
indexFile.writeLn("</BODY>");
indexFile.writeLn("</HTML>");
}
int scanDir (STRPTR startDir, STRPTR pattern, LONG linesInTable, LONG columnsInTable, BOOL picClick)
{
GUIC_ListC fileList,dirList;
GalleryEntryC *key = 0;
GUIC_FileExamineC *filex = 0;
int entries = 0;
GUIC_FileExamineC *examine = new GUIC_FileExamineC(startDir);
if (!examine->isDirectory()) throw GUIC_SystemX("Error in function ScanDir (directory name expected).");
String dirName = examine->getName();
delete examine; examine=0;
GUIC_DirectoryExamineC *direx= new GUIC_DirectoryExamineC(dirName);
BOOL hasSubDirs = direx->hasSubdirectory();
if (!hasSubDirs) direx->setFilter(FILEFILTER);
try
{
while ( (filex = direx->examineNext()) )
{
String fileName = filex->getName();
GUIC_DateC *date = filex->getDate();
if (filex->isDirectory())
{
String newPattern = String("../") + String(pattern);
int entriesInDir = scanDir(fileName, pattern ? (STRPTR) newPattern : 0, linesInTable, columnsInTable, picClick);
if (entriesInDir)
{
key = new GalleryEntryC(fileName, entriesInDir, lastDay, lastMonth, lastYear);
if (!key) throw GUIC_MemoryX("Can't allocate memory for key.");
dirList.addTail(*key);
entries+=entriesInDir;
}
lastDay=0; lastMonth=0; lastYear=0;
}
else if (! hasSubDirs && (fileName.right(5) != String("_.jpg") ) )
{
key = new GalleryEntryC(fileName, filex->getSize(), date->getDay(), date->getMonth(), date->getYear() );
if (!key) throw GUIC_MemoryX("Can't allocate memory for key.");
fileList.addTail(*key);
entries++;
}
}
}
catch (GUIC_SystemX &e) { cerr << "Exception caught while processing directory '" << direx->getName() << "': " << e.getMessage() << endl; }
delete direx;direx=0; /* Damit der lock auf das Verzeichnis freigegeben wird ! */
if (dirList.length()) createHTML (dirList,pattern);
if (fileList.length()) createGallery (fileList,pattern, linesInTable, columnsInTable, picClick);
while (fileList.length()) delete (GalleryEntryC *)fileList.remove(1);
while ( dirList.length()) delete (GalleryEntryC *) dirList.remove(1);
return entries;
}
class GalleryWindowC : public GUIC_WindowC
{
public:
GalleryWindowC (GUIC_ApplicationC *app, GUIC_ScreenC *screen);
~GalleryWindowC (void);
BOOL action (GUIC_EventC &);
private:
GUIC_ButtonC *start, *quit;
GUIC_FileStringC *pattern;
GUIC_PathStringC *directory;
GUIC_SlidingIntegerC *lines, *columns;
GUIC_FrameC *frame;
GUIC_CheckboxC *click;
GUIC_LabelC *dirLabel, *pattLabel, *linesLabel, *columnsLabel, *clickLabel;
};
GalleryWindowC::GalleryWindowC (GUIC_ApplicationC *app, GUIC_ScreenC *screen) : GUIC_WindowC (-1,-1,46,19)
{
frame = new GUIC_FrameC (1,1,44,14,"Gallery");
dirLabel = new GUIC_LabelC (3, 2,10,2,"_Directory:");
pattLabel = new GUIC_LabelC (3, 4,10,2,"_Pattern:");
linesLabel = new GUIC_LabelC (3, 7,10,2,"_Lines:");
columnsLabel = new GUIC_LabelC (3, 9,10,2,"_Columns:");
clickLabel = new GUIC_LabelC (3,12,30,2,"Use _thumbnail picture as link:");
directory = new GUIC_PathStringC (13, 2,30,2,"");
pattern = new GUIC_FileStringC (13, 4,30,2,"");
lines = new GUIC_SlidingIntegerC (13, 7,30,2,MINLINES,MAXLINES,DEFAULTLINES);
columns = new GUIC_SlidingIntegerC (13, 9,30,2,MINCOLUMNS,MAXCOLUMNS,DEFAULTCOLUMNS);
click = new GUIC_CheckboxC (40,12, 3,2,FALSE);
start = new GUIC_ButtonC (1,16,15,2,"_Start");
quit = new GUIC_ButtonC (30,16,15,2,"_Quit");
directory ->setHelp("Directory for the first index file.");
pattern ->setHelp("Background pattern in HTML pages.");
lines ->setHelp("The number of lines per HTML table.");
columns ->setHelp("The number of columns per HTML table.");
click ->setHelp("Click on thumbnails to view picture?");
start ->setHelp("Start the creation of the gallery.");
quit ->setHelp("Quit the program.");
directory ->setShortcut('d');
pattern ->setShortcut('p');
lines ->setShortcut('l');
columns ->setShortcut('c');
click ->setShortcut('t');
start ->setShortcut('s');
quit ->setShortcut('q');
add(frame);
add(dirLabel);
add(directory);
add(pattLabel);
add(pattern);
add(linesLabel);
add(lines);
add(columnsLabel);
add(columns);
add(clickLabel);
add(click);
add(start);
add(quit);
app->addPrefs("GalleryWindow" , this);
app->addPrefs("StartDirectory" , directory);
app->addPrefs("BackgroundPattern" , pattern);
app->addPrefs("NumberOfLines" , lines);
app->addPrefs("PictureAsLink" , click);
app->addPrefs("NumberOfColumns" , columns);
setTitle("Gallery - (c) by Markus Hillenbrand");
setHelp(TRUE);
activate();
}
GalleryWindowC::~GalleryWindowC (void)
{
delete frame;
delete dirLabel;
delete directory;
delete pattLabel;
delete pattern;
delete linesLabel;
delete lines;
delete columnsLabel;
delete columns;
delete clickLabel;
delete click;
delete start;
delete quit;
}
BOOL GalleryWindowC::action(GUIC_EventC &e)
{
switch (e.id)
{
case GUIC_GadgetEvent:
if (e.gadget == (GUIC_GadgetC *)start)
{
if (! strcmp(directory->get(), "") )
{
GUIC_ErrorC e("You must at least enter a directory name!");
e.request(this);
}
else
{
GUIC_SystemC::openConsole();
sleep();
activate();
try
{
scanDir (directory->get(), pattern->get(), lines->get(), columns->get(), click->get() );
}
catch (GUIC_Exception &x) { GUIC_ErrorC e("Exception caught:", x.getMessage() ); e.request(this); }
waken();
}
}
else if (e.gadget == (GUIC_GadgetC *)quit)
{
dispose();
}
return TRUE;
break;
case GUIC_CloseWindow:
return TRUE;
break;
default:
cerr << "Got an event: " << e.id << endl;
}
return FALSE;
}
void shell (void)
{
LONG result[] = { 0,0,0,0,0 };
STRPTR templ = "STARTDIR/A,LINES/N,COLUMNS/N,BGPATTERN,PICCLICK/S";
GUIC_ProgramArgsC args;
if (! args.fit(templ, result))
{
cerr << "Usage: " << templ << endl;
GUIC_SystemC::exit(GUIC_ExitError);
}
LONG lines = result[1] ? *(LONG *)result[1] : DEFAULTLINES;
if (lines < MINLINES) lines=MINLINES;
if (lines > MAXLINES) lines=MAXLINES;
LONG columns = result[2] ? *(LONG *)result[2] : DEFAULTCOLUMNS;
if (columns < MINCOLUMNS) columns=MINCOLUMNS;
if (columns > MAXCOLUMNS) columns=MAXCOLUMNS;
BOOL picclick = result[4];
scanDir((STRPTR)result[0], (STRPTR)result[3], lines, columns, picclick);
if (errorList.length())
{
cerr << "The following files could not be converted to a thumbnail:" << endl;
while (errorList.length())
{
GalleryEntryC *s = (GalleryEntryC *)errorList.remove(1);
cerr << "- " << s->fileName << endl;
delete s;
}
cerr << "Please check them and run 'Gallery' again." << endl;
}
}
void workbench (void)
{
GUIC_ApplicationC app("Gallery");
app.setAuthor (__AUTHOR__);
app.setVersion (__VERSION__);
app.setRevision (__REVISION__);
app.setDate (__DATE__);
app.setTime (__TIME__);
app.setInitializer (TRUE);
GUIC_ScreenC screen;
GalleryWindowC window(&app, &screen);
screen.add(window);
app.add(screen);
app.start();
BOOL running = TRUE;
GUIC_EventC *event = 0;
int count = 0;
while (running && (event = app.wait()) )
{
// As we have only one window, it is not neccessary to check for the window id
if (event->id == GUIC_CloseWindow)
{
GUIC_MessageC message ("Do you really want to quit ?", "Yes|No");
if (1 == message.request(*event->window)) running = FALSE;
}
}
app.stop();
}
void main (int argc, char **argv)
{
GUIC_SystemC::checkStackSize(50000);
if (GUIC_SystemC::runFromShell() ) shell(); else workbench();
}